Skip to content

lab(lab6): Dockerize QuickNotes β€” multi-stage + compose + hardening#1201

Open
GrandAdmiralBee wants to merge 5 commits into
inno-devops-labs:mainfrom
GrandAdmiralBee:feature/lab6
Open

lab(lab6): Dockerize QuickNotes β€” multi-stage + compose + hardening#1201
GrandAdmiralBee wants to merge 5 commits into
inno-devops-labs:mainfrom
GrandAdmiralBee:feature/lab6

Conversation

@GrandAdmiralBee

Copy link
Copy Markdown

Goal

Lab 6 submission β€” multi-stage Dockerfile for QuickNotes (≀25 MB target, lands 14.6 MB), distroless-static-nonroot runtime, compose with named-volume persistence + healthcheck, and all 6 hardening defaults applied + Trivy before/after.

Changes

  • app/Dockerfile β€” multi-stage: golang:1.24.13-alpine builder β†’ gcr.io/distroless/static-debian12:nonroot runtime. CGO_ENABLED=0, -trimpath -ldflags='-s -w', deps-before-source layer order, /data precreated nonroot for self-sufficient docker run.
  • app/cmd/healthcheck/main.go β€” tiny static Go binary (~20 LoC, no deps) that hits /health and exits 0/1. Solves the "distroless has no shell" healthcheck problem from inside the image.
  • compose.yaml β€” service quicknotes with named volume quicknotes-data:/data, healthcheck via ["CMD", "/healthcheck"], env defaults, restart: unless-stopped, port 127.0.0.1:8080:8080 (loopback), plus all 6 hardening defaults: user 65532:65532, read_only: true + tmpfs /tmp, cap_drop: [ALL], security_opt: [no-new-privileges:true].
  • submissions/lab6.md β€” Dockerfile+compose paste, image inspect, smoketest, persistence cycle (PRESENT-1 β†’ PRESENT-2 β†’ GONE), all 7 design questions answered, 5 per-default verification commands captured, Trivy before/after table showing the supply-chain story of pinning vs auto-bump.

Testing

  • docker build β€” final image 14.6 MB (under 25 MB cap).
  • docker run --name qn-smoketest -p 18080:8080 quicknotes:lab6 + curl :18080/health β†’ {"notes":4,"status":"ok"}.
  • docker compose up --build -d β†’ healthy after first interval; POST/GET/down/up/down -v cycle verified.
  • 6 hardening verifications: User=nonroot:nonroot, sh not found (both forms), cap_drop expanded list, ReadonlyRootfs=true (+ Alpine sidecar proof), SecurityOpt=[no-new-privileges].
  • Trivy: 0 OS HIGH/CRITICAL throughout; Go stdlib went 32 β†’ 26 H+C after bumping 1.24.5 β†’ 1.24.13; remaining 13Γ—2 are fix-only-in-1.25.x β†’ Go 1.24 EOL story documented.

Checklist

  • Title is a clear sentence (≀ 70 chars)
  • Commits are signed
  • app/Dockerfile, compose.yaml, submissions/lab6.md all present
  • CI on this PR will run on the existing Go 1.23/1.24 matrix (no workflow changes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant